
#include <iostream>
#include <string>
#include <crafter.h>

/* Collapse namespaces */
using namespace std;
using namespace Crafter;

string getMACaddr(int s, const string& iface, const string& ip_addr) {
        /* Get the IP address associated to the interface */
        string MyIP = GetMyIP(iface);
        /* Get the MAC Address associated to the interface */
        string MyMAC = GetMyMAC(iface);

        Ethernet ether_header;

        ether_header.SetSourceMAC(MyMAC);
        ether_header.SetDestinationMAC("ff:ff:ff:ff:ff:ff");

        ARP arp_header;

        arp_header.SetOperation(ARP::Request);
        arp_header.SetSenderIP(MyIP);
        arp_header.SetSenderMAC(MyMAC);
        arp_header.SetTargetIP(ip_addr);

        Packet arp_pck = ether_header / arp_header;

        /* We use the socket provided */
        Packet* rcv = arp_pck.SocketSendRecv(s,iface);

        string ret = "";

        if(rcv) {
                ARP* arp_layer = rcv->GetLayer<ARP>();

                /* Get the MAC */
                ret = arp_layer->GetSenderMAC();

                delete rcv;
        }

        return ret;
}

int main(int argc, char *argv[]) {

        /* Set the interface */
        string iface = "wlan0";

        int rawsock;

        if((rawsock = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)))== -1)
                exit(1);

        struct sockaddr_ll sll;
        struct ifreq ifr;

        memset(&sll,0,sizeof(sll));
        memset(&ifr,0,sizeof(ifr));

        /* First Get the Interface Index  */
        strncpy((char *)ifr.ifr_name, iface.c_str(), IFNAMSIZ);
        if((ioctl(rawsock, SIOCGIFINDEX, &ifr)) == -1)
        {
                perror("Getting Interface index");
                exit(1);
        }

        /* Bind our raw socket to this interface */
        sll.sll_family = AF_PACKET;
        sll.sll_ifindex = ifr.ifr_ifindex;
        sll.sll_protocol = htons(ETH_P_ALL);


        if((bind(rawsock, (struct sockaddr *)&sll, sizeof(sll)))== -1)
        {
                perror("Binding raw socket to interface");
                exit(1);
        }

        /* Get the MAC address of some IPs devices */
        cout << getMACaddr(rawsock,iface,argv[1]) << endl;

        close(rawsock);

        return 0;
}